package com.boil.qz.safekavass.service;

import com.boil.pojo.ResultVo;
import com.boil.qz.safekavass.dao.MybatisDao;
import com.boil.qz.safekavass.model.LoginUser;
import com.boil.qz.safekavass.model.ResourceEntity;
import com.boil.qz.safekavass.model.RoleEntity;
import com.boil.qz.safekavass.pojo.RoleVo;
import com.boil.qz.safekavass.pojo.UserRoleVo;
import com.boil.qz.safekavass.web.request.param.PermissionUpdateParam;
import com.boil.util.Constants;
import com.boil.util.DateUtils;
import com.boil.util.Page;
import com.boil.util.Utils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * Created by ChenYong on 2017-08-09.
 * <br>
 * 权限 Service。
 */
@Service
public class PermissionService {
    /**
     * 注入 Mybatis Dao
     */
    @Autowired
    private MybatisDao mybatisDao;
    /**
     * 注入角色 Service
     */
    @Autowired
    private RoleService roleService;
    /**
     * 注入用户 Service
     */
    @Autowired
    private LoginUserService loginUserService;

    /**
     * 分页查询用户角色关联。
     *
     * @param page 分页实例
     */
    public void findInPage(Page<UserRoleVo> page) {
        mybatisDao.selectInPage("permissionNs.findInPage", page);
    }

    /**
     * 用户已拥有或未拥有的角色 <code>List</code>。
     *
     * @param resultVo 结果 Vo
     * @param userId   用户 ID
     */
    public void findRoleVo(ResultVo resultVo, long userId) {
        if (resultVo != null) {
            // 查询用户已拥有的角色 List
            List<RoleEntity> myRoleEntities = roleService.findMyByUserId(userId);
            // 查询用户未拥有的角色 List
            List<RoleEntity> otherRoleEntities = roleService.findOtherByUserId(userId);
            // 存放用户已拥有的角色
            List<RoleVo> myRoleVos = getRoleVos(myRoleEntities);
            // 存放用户未拥有的角色
            List<RoleVo> otherRoleVos = getRoleVos(otherRoleEntities);

            resultVo.getResults().add(myRoleVos);
            resultVo.getResults().add(otherRoleVos);
        }
    }

    /**
     * 分配权限。
     *
     * @param param 分配权限的请求参数
     */
    public void doPermission(PermissionUpdateParam param) {
        if (param != null) {
            // 查询用户
            LoginUser loginUser = loginUserService.findOne(param.getId());
            // 查询角色
            List<RoleEntity> roleEntities = roleService.findAll(Utils.parseStr2List(param.getRoleIds(), Constants.SPLIT_1_RE, Long.class));

            // 解除用户与角色的关联关系
            loginUser.getRoles().clear();

            // 给用户分配角色
            loginUser.getRoles().addAll(roleEntities);
        }
    }

    /**
     * 获取角色映射实例 <code>List</code>。
     *
     * @param roleEntities 角色实例 <code>List</code>
     * @return 角色映射实例 <code>List</code>
     */
    private List<RoleVo> getRoleVos(List<RoleEntity> roleEntities) {
        List<RoleVo> roleVos = new ArrayList<RoleVo>();

        if ((roleEntities != null) && !roleEntities.isEmpty()) {
            Iterator<RoleEntity> myRoleEntityIterator = roleEntities.iterator();
            while (myRoleEntityIterator.hasNext()) {
                RoleEntity roleEntity = myRoleEntityIterator.next();
                List<String> resourceNames = new ArrayList<String>();
                List<String> permissionCodes = new ArrayList<String>();

                Iterator<ResourceEntity> resourceEntityIterator = roleEntity.getResources().iterator();
                while (resourceEntityIterator.hasNext()) {
                    ResourceEntity resourceEntity = resourceEntityIterator.next();

                    resourceNames.add(resourceEntity.getResourceName());
                    permissionCodes.add(resourceEntity.getPermissionCode());
                }

                RoleVo roleVo = new RoleVo();
                roleVo.setId(roleEntity.getId());
                roleVo.setRoleName(roleEntity.getRoleName());
                roleVo.setRoleCode(roleEntity.getRoleCode());
                roleVo.setResourceNames(Utils.parseList2Str(resourceNames, Constants.COMMA_CHAR));
                roleVo.setPermissionCodes(Utils.parseList2Str(permissionCodes, Constants.COMMA_CHAR));
                roleVo.setCreateTime(DateUtils.format(roleEntity.getCreateTime(), Constants.DATE_TIME_FORMAT_1));

                roleVos.add(roleVo);
            }
        }

        return roleVos;
    }
}